package com.hjl.sr;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;

import com.hjl.sr.remoting.ExportService;
import com.hjl.sr.remoting.TokenSeviceProvider;
import com.hjl.sr.security.SecurityHttpInvokerServiceExporter;
import com.hjl.sr.security.SecurityUtil;
import com.hjl.sr.util.ServletUtil;

public class DefaultSecurityServer implements SecurityServer {

	private ConcurrentHashMap<String, ExportService> exportServices = new ConcurrentHashMap<String, ExportService>();

	private ConcurrentHashMap<String, HttpInvokerServiceExporter> invokerServiceExporters = new ConcurrentHashMap<String, HttpInvokerServiceExporter>();

	private String tokenServiceName = "/tokenService";

	public void addService(String name, Class<?> exportInterface, Object service) {
		if (!name.startsWith("/")) {
			name = "/" + name;
		}
		exportServices.put(name, new ExportService(exportInterface, service));
	}

	public void setTokenServiceName(String tokenServiceName) {
		this.tokenServiceName = tokenServiceName;
	}

	public void init(ServletConfig config) {
		for (Map.Entry<String, ExportService> entry : exportServices.entrySet()) {
			String name = entry.getKey();
			ExportService exportService = entry.getValue();
			String key = config.getInitParameter("encrypt-key");
			if (key == null) {
				key = SecurityUtil.DEFAULT_ENCRYPT_KEY;
			} else {
				key = key.trim();
			}
			SecurityHttpInvokerServiceExporter httpInvokerServiceExporter = new SecurityHttpInvokerServiceExporter(key);
			httpInvokerServiceExporter.setService(exportService.getService());
			httpInvokerServiceExporter.setServiceInterface(exportService.getExportInterface());
			httpInvokerServiceExporter.afterPropertiesSet();

			invokerServiceExporters.put(name, httpInvokerServiceExporter);
		}

		TokenSeviceProvider tokenSeviceProvider = new TokenSeviceProvider();
		tokenSeviceProvider.afterPropertiesSet();
		invokerServiceExporters.put(tokenServiceName, tokenSeviceProvider);
	}

	protected String getMatchPath(String pathInfo) {
		return pathInfo;
	}
	
	public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String pathInfo = ServletUtil.getServletPath(request);
		pathInfo = getMatchPath(pathInfo);
		HttpInvokerServiceExporter httpInvokerServiceExporter = invokerServiceExporters.get(pathInfo);
		if (httpInvokerServiceExporter == null) {
			throw new RuntimeException("can not find path info: " + pathInfo);
		}
		httpInvokerServiceExporter.handleRequest(request, response);
	}

}
